import tkinter as tk from PIL import Image, ImageTk import pygame import random import time import os import glob # Initialize pygame mixer pygame.mixer.init() # Paths IMAGE_FOLDER = "C:/Users/Admin/PycharmProjects/PythonProject1/Images/Animals/" AUDIO_FOLDER = "C:/Users/Admin/PycharmProjects/PythonProject1/Audio/Audioanimals/" FEEDBACK_AUDIO_FOLDER = "C:/Users/Admin/PycharmProjects/PythonProject1/Audio/" RIGHT_ANSWER_AUDIO = os.path.join(FEEDBACK_AUDIO_FOLDER, "Rightanswer.mp3") WRONG_ANSWER_AUDIO = os.path.join(FEEDBACK_AUDIO_FOLDER, "Wronganswer.mp3") # Load images and audio files image_files = glob.glob(os.path.join(IMAGE_FOLDER, "*.jpg")) audio_files = glob.glob(os.path.join(AUDIO_FOLDER, "*.mp3")) # Normalize paths for matching image_files = [os.path.normpath(img) for img in image_files] audio_files = [os.path.normpath(audio) for audio in audio_files] # Create quiz data quiz_data = [] for img in image_files: letter = os.path.splitext(os.path.basename(img))[0] # Extract 'A' from 'A.png' audio_path = os.path.join(AUDIO_FOLDER, f"{letter}.mp3") audio_path = os.path.normpath(audio_path) if audio_path in audio_files: # Generate random incorrect options incorrect_options = random.sample([a for a in audio_files if a != audio_path], 3) options = [audio_path] + incorrect_options random.shuffle(options) quiz_data.append({"image": img, "options": options, "answer": audio_path}) # Check if there are valid questions if not quiz_data: print("No valid images or matching audio files found.") exit() class QuizApp: def __init__(self, root): self.root = root self.root.title("Alphabet Image-Audio Quiz") self.root.state('zoomed') # Opens in maximized mode self.asked_questions = set() # Main layout container self.main_frame = tk.Frame(self.root) self.main_frame.pack(expand=True, fill="both") # Left Side - Image self.image_frame = tk.Frame(self.main_frame) self.image_frame.pack(side="left", padx=50, pady=20) self.image_label = tk.Label(self.image_frame) self.image_label.pack() # Right Side - Options self.options_frame = tk.Frame(self.main_frame) self.options_frame.pack(side="right", padx=50, pady=20) self.option_buttons = [] for i in range(4): btn = tk.Button( self.options_frame, text=f"Option {i + 1}", font=("Arial", 24, "bold"), # Larger font size width=30, # Increase button width height=3, # Increase button height bg="red", # Red background fg="white", # White text activebackground="darkred", # Button changes to dark red when clicked activeforeground="white", # Keep text white when clicked command=lambda i=i: self.check_answer(i) ) btn.pack(pady=15) # Increased padding between buttons self.option_buttons.append(btn) # Feedback label (centered below the buttons) self.feedback_label = tk.Label(self.options_frame, text="", font=("Arial", 26, "bold"), fg="black") self.feedback_label.pack(pady=20) # Load first question self.load_question() def load_question(self): """Load a new random question""" if len(self.asked_questions) == len(quiz_data): self.feedback_label.config(text="🎉 Quiz Completed! 🎉", fg="blue") return while True: self.current_question = random.choice(quiz_data) if self.current_question["image"] not in self.asked_questions: self.asked_questions.add(self.current_question["image"]) break # Load and display image (Increase size to 900x800) image = Image.open(self.current_question["image"]) image = image.resize((900, 800)) # Increased size photo = ImageTk.PhotoImage(image) self.image_label.config(image=photo) self.image_label.image = photo # Assign shuffled options for i, option in enumerate(self.current_question["options"]): file_name = os.path.splitext(os.path.basename(option))[0] # Extract only filename without extension self.option_buttons[i].config(text=file_name, command=lambda i=i: self.check_answer(i)) # Reset feedback text self.feedback_label.config(text="") # Auto-play all options sequentially self.root.after(500, self.auto_play_options) def auto_play_options(self): """Play all audio options sequentially""" for option in self.current_question["options"]: pygame.mixer.music.load(option) pygame.mixer.music.play() while pygame.mixer.music.get_busy(): time.sleep(1) def check_answer(self, index): """Check answer and play correct/incorrect audio""" selected_audio = self.current_question["options"][index] if selected_audio == self.current_question["answer"]: self.feedback_label.config(text="✅ Correct Answer!", fg="green") self.play_feedback_audio(RIGHT_ANSWER_AUDIO) else: self.feedback_label.config(text="❌ Wrong Answer!", fg="red") self.play_feedback_audio(WRONG_ANSWER_AUDIO) # Load the next question after a short delay self.root.after(1500, self.load_question) def play_feedback_audio(self, audio_path): """Play feedback audio for correct/wrong answer""" pygame.mixer.music.load(audio_path) pygame.mixer.music.play() while pygame.mixer.music.get_busy(): time.sleep(0.5) # Ensure audio plays fully before continuing # Ensure that Tkinter starts only once if __name__ == "__main__": root = tk.Tk() root.state('zoomed') # Opens in maximized mode app = QuizApp(root) root.mainloop()